﻿using S7.Net;
using S7.Net.Types;

namespace SimS7Study_Tuling
{
    internal class Program
    {
        static void Main(string[] args)
        {
            using (var plc = new Plc(CpuType.S71200, "127.0.0.1", 0, 1))
            {
                try
                {
                    plc.Open();
                    if (plc.IsConnected)
                    {
                        Console.WriteLine("连接成功!");
                    }
                }
                catch (Exception)
                {
                    Console.WriteLine($"连接到PLC设备失败：IsConnect={plc.IsConnected}");
                    return;
                }

                #region 单个数据项读取
                //PLC数据类型:Bool(位),C# bool
                bool db1Bool1 = (bool)plc.Read("DB1.DBX0.0");
                Console.WriteLine(db1Bool1);

                bool db1Bool2 = (bool)plc.Read("DB1.DBX0.1");
                Console.WriteLine(db1Bool2);

                // PLC数据类型:Word,C# ushort
                ushort db1UShort = (ushort)plc.Read("DB1.DBW2");
                Console.WriteLine(db1UShort);

                // PLC数据类型:Real,C# float
                /**
                 *  DataType.DataBlock指定了我们要从数据块（Data Block, DB）中读取数据。
                 *  1是数据块的编号，表示我们想要访问DB1。
                 *  4是从该数据块的哪个字节开始读取数据。
                 *  VarType.Real指示我们想要读取的数据类型是REAL。
                 *  最后的1表示我们希望读取的元素数量，在本例中为1个REAL值。
                 */
                float realVariable = (float)plc.Read(DataType.DataBlock, 1, 4, VarType.Real, 1);
                Console.WriteLine(realVariable);

                // PLC数据类型DWord,C# uint
                uint uintVariable = (uint)plc.Read("DB1.DBD8");
                Console.WriteLine(uintVariable);
                #endregion

                #region 通过 ReadBytes 读取单个数据
                // 读取DB1中,从字节偏移量2开始的2个字节的数据
                byte[] int0 = (byte[])plc.ReadBytes(DataType.DataBlock, 1, 2, 2);
                byte[] revint0 = int0.Reverse().ToArray();
                ushort DB1_DBW2 = BitConverter.ToUInt16(revint0, 0);
                Console.WriteLine("DB1.DBW2======>" + DB1_DBW2);
                #endregion

                #region 批量读取数据块
                // DataType: 数据类型，DB
                // 1: 数据块编号，DB1
                // 0: 起始字节偏移量，表示从DB1的第0个字节开始读取
                // 18: 要读取的字节数，表示我们要从DB1中读取18个字节的数据
                var bytes = plc.ReadBytes(DataType.DataBlock, 1, 0, 18);
                //Console.WriteLine(bytes);


                var bool1 = bytes[0].SelectBit(0); // DB1.DBX0.0
                Console.WriteLine("DB1.DBX0.0:" + bool1);

                var bool2 = bytes[0].SelectBit(1); // DB1.DBX0.1
                Console.WriteLine("DB1.DBX0.1:" + bool2);

                // PLC int类型,C# short
                short shortVariable = S7.Net.Types.Int.FromByteArray(bytes.Skip(2).Take(2).ToArray());
                Console.WriteLine("DB1.DBW2:" + shortVariable); // DB1.DBW2.0

                // PLC数据类型:Real,C# float
                float floatVariable = S7.Net.Types.Real.FromByteArray(bytes.Skip(4).Take(4).ToArray());
                Console.WriteLine("DB1.DBD4:" + floatVariable); // DB1.DBD4.0

                // PLC数据类型DWord,C# uint
                uint uintVariable2 = S7.Net.Types.DWord.FromByteArray(bytes.Skip(8).Take(4).ToArray());
                Console.WriteLine("DB1.DBD8:" + uintVariable2); // DB1.DBD8.0

                // PLC数据类型:Word,C# ushort
                ushort ushortvariable = S7.Net.Types.Word.FromByteArray(bytes.Skip(16).Take(2).ToArray());
                Console.WriteLine("DB1.DBW16:" + ushortvariable); // DB1.DBW16.0
                #endregion


                #region 写入单个数据
                plc.Write("DB1.DBD12", 123457);
                #endregion


                #region 取数据块（DB）到实体类
                DB db1 = new DB();
                plc.ReadClass(db1, 1, 0);
                #endregion


                Console.ReadKey();
            }
        }
    }

    public class DB
    {
        public bool varBool0 { get; set; } // DB1.DBX0.0
        public bool varBool1 { get; set; } // DB1.DBX0.1
        public short varWord2 { get; set; } // DB1.DBW2
        public float varReal4 { get; set; } // DB1.DBD4
        public uint varDWord8 { get; set; } // DB1.DBD8
        public uint varDWord12 { get; set; } // DB1.DBD12
        public ushort varWord16 { get; set; } // DB1.DBW16
    }
}
